﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using vJine.Core;
using vJine.Lua.GUI.BLL;
using ZedGraph;

namespace vJine.Lua.GUI.UI {
    /// <summary>
    /// NodeStatus.xaml 的交互逻辑
    /// </summary>
    public partial class NodeStatus : UserControl, IValueConverter {
        public NodeStatus() {
            InitializeComponent();

            this.Loaded += NodeStatus_Loaded;
            this.Unloaded += NodeStatus_Unloaded;
        }

        public void set_view_status(bool is_degine_mode) {
            this.luaParams.set_view_mode(is_degine_mode);
            this.luaResults.set_view_mode(is_degine_mode);
            this.luaData.set_view_mode(is_degine_mode);
            this.luaProgs.set_view_mode(is_degine_mode);
        }

        bool IsLoaded = false;
        void NodeStatus_Loaded(object sender, RoutedEventArgs e) {
            this.IsLoaded = true;
        }

        void NodeStatus_Unloaded(object sender, RoutedEventArgs e) {
            this.IsLoaded = false;
        }

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            return (int)value - 1;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            return (int)value + 1;
        }

        #region

        NodeConfig luaConfig { get; set; }
        LuaContext luaContext { get; set; }

        private void UserControl_GotFocus(object sender, RoutedEventArgs e) {
            //this.on_hook(); //FIX:此处调用HOOK系统CRASH
        }

        void set_readonly(bool is_readonly) {
            this.Dispatcher.BeginInvoke(new Action(() => {
                luaParams.set_readonly(is_readonly);
                luaData.set_readonly(is_readonly);
                luaResults.set_readonly(is_readonly);
                luaProgs.set_readonly(is_readonly);
            }));
        }

        public event Action<bool> on_running;
        public void set_bound(AppGUI appGUI, LuaContext luaContext, NodeConfig runConfig, Action<string, string, MessageBoxButton, MessageBoxImage> show_messge = null) {
            appGUI.SwitchPresentor(this.rtbMessage, this.Dispatcher);

            runConfig.on_begin += (NodeConfig cmd) => {
                lock (this) {
                    if (!this.IsLoaded) {
                        return;
                    }

                    this.set_readonly(true);

                    if (this.on_running != null) {
                        this.on_running(true);
                    }
                }
            };
            bool trig_on_changed = true;
            runConfig.on_pause += (NodeConfig node, bool isBefore) => {
                lock (this) {
                    if (!this.IsLoaded) {
                        return;
                    }

                    this.set_readonly(false);

                    trig_on_changed = runConfig.trig_on_changed;
                    runConfig.trig_on_changed = true;

                    if (node != null) {
                        UI.WinParamTune.show_tune(luaContext, isBefore? node.pause_message : node.pause_after_message, runConfig, node);
                    }
                }
            };
            runConfig.on_continue += () => {
                lock (this) {
                    if (!this.IsLoaded) {
                        return;
                    }

                    this.set_readonly(true);

                    runConfig.trig_on_changed = trig_on_changed;
                }
            };
            runConfig.on_finish += (NodeConfig cmd) => {
                lock (this) {
                    if (!this.IsLoaded) {
                        return;
                    }

                    this.set_readonly(false);

                    if (this.on_running != null) {
                        this.on_running(false);
                    }
                }
            };

            //runConfig.IsActive = true; //TODO: 如果不设置则运行测试用例及测试用例中的节点时无法绑定【取消】按钮的状态
            runConfig.luaContext = luaContext;


            this.DataContext = runConfig;
            this.btnRun.Command = runConfig;
            this.btnRun.SetBinding(Button.ContentProperty, "cmd_run");
            this.btnRun.SetBinding(Button.CommandParameterProperty, "cmd_run_param");

            this.btnCancel.Command = runConfig;
            this.btnIgnore.Command = runConfig;            

            this.luaContext = luaContext;
            this.luaConfig = runConfig;

            this.luaParams.TYPE = LuaOptionType.W;
            this.luaParams.luaContext = luaContext;
            this.luaResults.TYPE = LuaOptionType.R;
            this.luaResults.luaContext = luaContext;
            this.luaProgs.TYPE = LuaOptionType.P;
            this.luaProgs.luaContext = luaContext;
            this.luaData.TYPE = LuaOptionType.D;
            this.luaData.luaContext = luaContext;

            NodeConfig configI = new NodeConfig();
            NodeConfig configO = new NodeConfig();
            NodeConfig configD = new NodeConfig();
            NodeConfig configP = new NodeConfig();

            if (runConfig.configs == null || runConfig.configs.Count == 0) {
                this.luaParams.set_bound(null);
                this.luaResults.set_bound(null);
                this.luaData.set_bound(null);
                this.luaProgs.set_bound(null);
            } else {
                for (int i = 0, len = runConfig.configs.Count; i < len; i++) {
                    NodeConfig config_i = runConfig.configs[i];
                    if (!config_i.w && !config_i.r && !config_i.data && !config_i.p)
                    {
                        config_i.w = true;
                    }
                    if (config_i.w)
                    {
                        configI.Add(config_i);
                    }
                    if (config_i.r) {
                        configO.Add(config_i);
                    }
                    if (config_i.data) {
                        configD.Add(config_i);
                    }
                    if (config_i.p) {
                        configP.Add(config_i);
                    }
                }

                this.luaParams.set_bound(configI);
                this.luaResults.set_bound(configO);
                this.luaData.set_bound(configD);
                this.luaProgs.set_bound(configP);
            }

            this.luaConfig.OnProgress += (double progMain, double progSub) => {
                this.Dispatcher.BeginInvoke(new Action(() => {
                    this.uctProgress.ProgMain = progMain;
                    this.uctProgress.ProgSub = progSub;
                }));
            };
        }
        #endregion

        private void txtParam_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
            string param_file = this.txtParam.Text.Trim();
            bool has_params = false;
            NodeConfig configs = this.luaConfig.configs;
            if (configs != null && configs.Count > 0) {
                for (int i = 0, len = configs.Count; i < len; i++) {
                    if (configs[i].w == true) {
                        has_params = true; break;
                    }
                }
            }
            if (!has_params) {
                MessageBox.Show(
                    "请设置【输入参数】后再尝试【生成参数模板】", "操作错误",
                    MessageBoxButton.OK, MessageBoxImage.Stop);
                return;
            }
            if (string.IsNullOrEmpty(param_file)) {
                MessageBox.Show(
                    "请输入参数文件后重试", "操作错误",
                    MessageBoxButton.OK, MessageBoxImage.Stop);
                return;
            }
            if (File.Exists(param_file)) {
                if (MessageBox.Show(
                    "如果继续将【覆盖已有的参数文件】，确定要继续吗", "操作提示", 
                    MessageBoxButton.OKCancel, MessageBoxImage.Question) != MessageBoxResult.OK) {
                    return;
                }
            }

            string template_header = "";
            for (int i = 0, len = configs.Count; i < len; i++) {
                if (configs[i].w == true) {
                    template_header += i == 0 ? configs[i].param : "," + configs[i].param;
                }
            }
            File.WriteAllText(param_file, template_header + Environment.NewLine);
            MessageBox.Show(
                "【参数模板】已生成", "操作提示", 
                MessageBoxButton.OK, MessageBoxImage.Information
                );
        }
    }
}
